package model.code.line;

import event.TextReplacementEvent;
import model.code.CodeFileChunk;
import observer.Copiable;

/**
 * This interface is for all pieces of text that can be treated as a sequence of {@link Line}s.
 * @author Neil Dickson
 */
public interface LineList<E extends Line> extends Copiable<LineList<E>> {
	/**
	 * @return the {@link CodeFileChunk} containing this {@link LineList}
	 */
	CodeFileChunk getParent();

	/**
	 * @return the type of location where this LineList appears;
	 * possible values are the <tt>LOCATION_</tt> constants in {@link CodeFileChunk}
	 * @see #getLocationIndex
	 */
	int getLocationType();

	/**
	 * @return the index into the list or table for this LineList's location type, (row<<16 + col, if a table),
	 * or zero if there is only one LineList for the location type
	 */
	int getLocationIndex();

	/**
	 * @return the number of {@link Line}s in this LineList
	 */
	int size();

	/**
	 * @param index the index of the {@link Line} to get
	 * @return the {@link Line} at the specified index
	 * @throws ArrayIndexOutOfBoundsException if the index is >= size()
	 */
	E get(int index) throws ArrayIndexOutOfBoundsException;

	/**
	 * @param line the {@link Line} for which to search
	 * @return the index of the specified {@link Line} or -1 if not found
	 */
	int indexOf(E line);

	/**
	 * Inserts the specified text at the specified location.
	 * @param line the line in which to insert the text
	 * @param col the column at which to insert the text
	 * @param text the text to insert at the specified line and column
	 * @return an object representing what occured so that it can be undone
	 */
	TextReplacementEvent insert(int line,int col,String text);

	/**
	 * Replaces the text at the specified location with the specified text.
	 * @param startLine the first line of the text to be replaced
	 * @param startCol the first column on the first line of the text to be replaced
	 * @param endLine the last line of the text to be replaced (or the next line with endCol==0 if text ends in '\n')
	 * @param endCol the last column on the last line of the text to be replaced
	 * @param text the text with which to replace the specified caret
	 * @return an object representing what occured so that it can be undone
	 */
	TextReplacementEvent replace(int startLine,int startCol,int endLine,int endCol,String text);

	/**
	 * Retrieves the text in the specified location.
	 * @param startLine the first line of the text
	 * @param startCol the first column on the first line of the text
	 * @param endLine the last line of the text
	 * @param endCol the last column on the last line of the text
	 * @return the desired text
	 */
	String getText(int startLine,int startCol,int endLine,int endCol);

	/**
	 * @return a copy of this LineList with the same parent
	 */
	LineList<E> copy();

	/**
	 * @return a copy of this LineList with a new parent
	 */
	LineList<E> copy(CodeFileChunk parent);
}
